package com.logica.mdm.webservices.messages;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;

import com.logica.mdm.webservices.dao.beans.AddressResultBean;
import com.logica.mdm.webservices.dao.beans.PartyByMdmIdResultBean;
import com.logica.mdm.webservices.dao.beans.PartyElectronicAddressResultBean;
import com.logica.mdm.webservices.dao.beans.PartyRelResultBean;
import com.logica.mdm.webservices.dao.beans.XrefResultBean;
import com.logica.mdm.webservices.messages.beans.AddressBean;
import com.logica.mdm.webservices.messages.beans.PartyRelBean;
import com.logica.mdm.webservices.messages.beans.PartyWithAddressAndContractBean;
import com.logica.mdm.webservices.messages.beans.PartyWithAddressAndRelBean;
import com.logica.mdm.webservices.util.RequestWithParamsBean;

/**
 * Utility class to search MDM by MDM Id.
 */
public class SearchPartyByMdmIdUtils {
	
	/**
	 * Create a query compatible with the database from the search parameter to search a Party.
	 * @param searchParams the search parameter
	 * @return the corresponding query with parameters
	 */
	public static RequestWithParamsBean buildPartyRequest(SearchPartyByMdmIdRequest searchParams) {
		Map<String, Object> filterParams = new HashMap<String, Object>();
		
		if (!StringUtils.isEmpty(searchParams.getMdmId())) {
			filterParams.put("mdmId", searchParams.getMdmId().trim());
		}

		// Create the SearchQuery request
		RequestWithParamsBean request = new RequestWithParamsBean();
		request.setSqlQuery(SearchPartyByMdmIdConstants.PARTY_SEARCH_QUERY);
		request.setParams(filterParams);
		
		return request;
	}
	
	/**
	 * Create a query compatible with the Database from the party Id to search for Party addresses.
	 * @param partyId the party Id
	 * @return the corresponding query with parameters
	 */
	public static RequestWithParamsBean buildAddressRequest(String partyId) {
		Map<String, Object> filterParams = new HashMap<String, Object>();
		
		if (!StringUtils.isEmpty(partyId)) {
			filterParams.put("partyId", partyId);
		}

		// Create the SearchQuery request
		RequestWithParamsBean request = new RequestWithParamsBean();
		request.setSqlQuery(SearchPartyByMdmIdConstants.ADDRESS_SEARCH_QUERY);
		request.setParams(filterParams);
		
		return request;
	}
	
	/**
	 * Create a query compatible with the database from the party Id to search for Party partyRels.
	 * @param partyId the party Id
	 * @return the corresponding query with parameters
	 */
	public static RequestWithParamsBean buildPartyRelRequest(String partyId) {
		Map<String, Object> filterParams = new HashMap<String, Object>();
		
		if (!StringUtils.isEmpty(partyId)) {
			filterParams.put("partyId1", partyId);
			filterParams.put("partyId2", partyId);
		}

		// Create the SearchQuery request
		RequestWithParamsBean request = new RequestWithParamsBean();
		request.setSqlQuery(SearchPartyByMdmIdConstants.PARTY_REL_SEARCH_QUERY);
		request.setParams(filterParams);

		return request;
	}
	
	/**
	 * Create a query compatible with the database from the party Id to search for Party Electronic Addresses.
	 * @param partyId the party Id
	 * @return the corresponding query with parameters
	 */
	public static RequestWithParamsBean buildPartyElectronicAddressRequest(String partyId) {
		Map<String, Object> filterParams = new HashMap<String, Object>();
		
		if (!StringUtils.isEmpty(partyId)) {
			filterParams.put("partyId", partyId);
		}

		// Create the SearchQuery request
		RequestWithParamsBean request = new RequestWithParamsBean();
		request.setSqlQuery(SearchPartyByMdmIdConstants.PARTY_ELECTRONIC_ADDRESS_SEARCH_QUERY);
		request.setParams(filterParams);

		return request;
	}
	
	/**
	 * Create a query compatible with the database from the party Id to search for Party Electronic Addresses.
	 * @param partyId the party Id
	 * @return the corresponding query with parameters
	 */
	public static RequestWithParamsBean buildPartyElectronicAddressProRequest(String partyId) {
		Map<String, Object> filterParams = new HashMap<String, Object>();
		
		if (!StringUtils.isEmpty(partyId)) {
			filterParams.put("electronicAddressType", "PRO"); // Hardcoded to professional address
			filterParams.put("partyId", partyId);
		}

		// Create the SearchQuery request
		RequestWithParamsBean request = new RequestWithParamsBean();
		request.setSqlQuery(SearchPartyByMdmIdConstants.PARTY_ELECTRONIC_ADDRESS_PRO_SEARCH_QUERY);
		request.setParams(filterParams);

		return request;
	}
	
	/**
	 * Create a query compatible with the database from the party Id to search for Party CRM IDs.
	 * @param partyId the party Id
	 * @return the corresponding query with parameters
	 */
	public static RequestWithParamsBean buildPartyCrmIdRequest(String partyId) {
		Map<String, Object> filterParams = new HashMap<String, Object>();
		
		if (!StringUtils.isEmpty(partyId)) {
			filterParams.put("partyId", partyId);
		}

		// Create the SearchQuery request
		RequestWithParamsBean request = new RequestWithParamsBean();
		request.setSqlQuery(SearchPartyByMdmIdConstants.PARTY_CRM_ID_SEARCH_QUERY);
		request.setParams(filterParams);

		return request;
	}
	
	/**
	 * Create a query compatible with the database from the party Id to search for Party Logement IDs.
	 * @param partyId the party Id
	 * @return the corresponding query with parameters
	 */
	public static RequestWithParamsBean buildPartyLogementIdRequest(String partyId) {
		Map<String, Object> filterParams = new HashMap<String, Object>();
		
		if (!StringUtils.isEmpty(partyId)) {
			filterParams.put("partyId", partyId);
		}

		// Create the SearchQuery request
		RequestWithParamsBean request = new RequestWithParamsBean();
		request.setSqlQuery(SearchPartyByMdmIdConstants.PARTY_LOGEMENT_ID_SEARCH_QUERY);
		request.setParams(filterParams);

		return request;
	}
	
	/**
	 * Create a query compatible with the database from the party Id to search for Party Service IDs.
	 * @param partyId the party Id
	 * @return the corresponding query with parameters
	 */
	public static RequestWithParamsBean buildPartyServiceIdRequest(String partyId) {
		Map<String, Object> filterParams = new HashMap<String, Object>();
		
		if (!StringUtils.isEmpty(partyId)) {
			filterParams.put("partyId", partyId);
		}

		// Create the SearchQuery request
		RequestWithParamsBean request = new RequestWithParamsBean();
		request.setSqlQuery(SearchPartyByMdmIdConstants.PARTY_SERVICE_ID_SEARCH_QUERY);
		request.setParams(filterParams);

		return request;
	}
	
	/**
	 * Validate the input request.
	 * The request need a MDM Id.
	 * @param searchParams the search parameter
	 * @return <null> if the request is valid, a string with an error message if not
	 */
	public static String validateRequest(SearchPartyByMdmIdRequest searchParams) {
		// The result String
		String result = null;
		
		String mdmID = searchParams.getMdmId();
		
		if (StringUtils.isEmpty(mdmID)) {
			result = "Invalid input: you must specify a MDM ID";
		}
		
		return result;
	}
	
	/**
	 * Utility method to convert result AddressResultbean list to a list of Address beans.
	 * @param inputList the AddressResultbean List to convert
	 * @return the converted list
	 */
	public static List<AddressBean> convertAddressRecord(List<AddressResultBean> inputList) {
		List<AddressBean> result = new ArrayList<AddressBean>();
		
		if (inputList != null) {
			for (AddressResultBean record : inputList) {
				AddressBean address = mdmAddressToAddressBean(record);
				result.add(address);
			}
		}
		return result;
	}
	
	/**
	 * Utility method to convert result PartyRelResultBean list to a list of PartyRel beans.
	 * @param inputList the PartyRelResultBean List to convert
	 * @param mainPartyId the found party Id
	 * @return the converted list
	 */
	public static List<PartyRelBean> convertPartyRelRecord(List<PartyRelResultBean> inputList, String mainPartyId) {
		List<PartyRelBean> result = new ArrayList<PartyRelBean>();
		
		if (inputList != null) {
			for (PartyRelResultBean record : inputList) {
				PartyRelBean partyRel = mdmPartyRelToPartyRelBean(record, mainPartyId);
				result.add(partyRel);
			}
		}
		return result;
	}
	
	/**
	 * Utility method to convert result PartyElectronicAddressResultBean list to a list of electronic addresses.
	 * @param inputList the PartyElectronicAddressResultBean List to convert
	 * @return the converted list
	 */
	public static List<String> convertPartyElectronicAddressRecord(List<PartyElectronicAddressResultBean> inputList) {
		List<String> result = new ArrayList<String>();
		
		if (inputList != null) {
			for (PartyElectronicAddressResultBean record : inputList) {
				result.add(record.getElectronicAddress());
			}
		}
		return result;
	}
	
	/**
	 * Utility method to convert result XrefResultBean list to a list of source keys.
	 * @param inputList the XrefResultBean List to convert
	 * @return the converted list
	 */
	public static List<String> convertXrefRecord(List<XrefResultBean> inputList) {
		List<String> result = new ArrayList<String>();
		
		if (inputList != null) {
			for (XrefResultBean record : inputList) {
				result.add(record.getPkeySrcObject());
			}
		}
		return result;
	}	
	
	/**
	 * Convert a result from the database to a PartyWithAddressAndRelBean result.
	 * @param partyIn the result from the MDM
	 * @return the corresponding PartyWithAddressAndRelBean result
	 */
	public static PartyWithAddressAndRelBean mdmPartyToPartyBean(PartyByMdmIdResultBean partyIn) {
		PartyWithAddressAndRelBean result = null;
		if (partyIn != null) {
			result = new PartyWithAddressAndRelBean();
			
			if (!StringUtils.isEmpty(partyIn.getPartyType())) {
				result.setPartyTypeCode(partyIn.getPartyType());
			}
			if (!StringUtils.isEmpty(partyIn.getPartyTypeDisp())) {
				result.setPartyType(partyIn.getPartyTypeDisp());
			}
			if (!StringUtils.isEmpty(partyIn.getGenderCd())) {
				result.setGenderCode(partyIn.getGenderCd());
			}
			if (!StringUtils.isEmpty(partyIn.getGenderDisp())) {
				result.setGender(partyIn.getGenderDisp());
			}
			if (!StringUtils.isEmpty(partyIn.getLegalFormCd())) {
				result.setLegalFormCode(partyIn.getLegalFormCd());
			}
			if (!StringUtils.isEmpty(partyIn.getLibelleLegalForm())) {
				result.setLegalForm(partyIn.getLibelleLegalForm());
			}
			if (!StringUtils.isEmpty(partyIn.getNamePrefixCd())) {
				result.setNamePrefixCode(partyIn.getNamePrefixCd());
			}
			if (!StringUtils.isEmpty(partyIn.getNamePrefixDisp())) {
				result.setNamePrefix(partyIn.getNamePrefixDisp());
			}
			if (!StringUtils.isEmpty(partyIn.getLastName())) {
				result.setLastName(partyIn.getLastName());
			}
			if (!StringUtils.isEmpty(partyIn.getFirstName())) {
				result.setFirstName(partyIn.getFirstName());
			}
			if (partyIn.getBirthdate() != null) {
				result.setBirthdate(partyIn.getBirthdate());
			}
			if (!StringUtils.isEmpty(partyIn.getMaritalStatus())) {
				result.setMaritalStatusCode(partyIn.getMaritalStatus());
			}
			if (!StringUtils.isEmpty(partyIn.getMaritalStatusTypeDisp())) {
				result.setMaritalStatus(partyIn.getMaritalStatusTypeDisp());
			}
			if (partyIn.getNumberOfChildren() != null) {
				result.setNumberOfChildren(partyIn.getNumberOfChildren());
			}
			if (!StringUtils.isEmpty(partyIn.getSocialCategory())) {
				result.setSocialCategoryCode(partyIn.getSocialCategory());
			}
			if (!StringUtils.isEmpty(partyIn.getSocialCategoryLabel())) {
				result.setSocialCategory(partyIn.getSocialCategoryLabel());
			}
			if (!StringUtils.isEmpty(partyIn.getTaxId())) {
				result.setTaxId(partyIn.getTaxId());
			}			
			if (!StringUtils.isEmpty(partyIn.getHomePhoneNumber())) {
				result.setHomePhoneNumber(partyIn.getHomePhoneNumber());
			}
			if (!StringUtils.isEmpty(partyIn.getCellPhoneNumber())) {
				result.setCellPhoneNumber(partyIn.getCellPhoneNumber());
			}
			if (!StringUtils.isEmpty(partyIn.getWorkPhoneNumber())) {
				result.setWorkPhoneNumber(partyIn.getWorkPhoneNumber());
			}
			if (!StringUtils.isEmpty(partyIn.getFaxPhoneNumber())) {
				result.setFaxPhoneNumber(partyIn.getFaxPhoneNumber());
			}
			if (!StringUtils.isEmpty(partyIn.getRowidObject())) {
				result.setMdmId(partyIn.getRowidObject());
			}
			if (!StringUtils.isEmpty(partyIn.getDebranchementSigeo())) {
				result.setSigeoId(partyIn.getDebranchementSigeo());
			}
		}
		return result;
	}
	
	/**
	 * Convert a Datatbase Address to an address Bean
	 * @param addressIn the database Address
	 * @return the corresponding AddressBean 
	 */
	private static AddressBean mdmAddressToAddressBean(AddressResultBean addressIn) {
		AddressBean result = null;
		if (addressIn != null) {
			result = new AddressBean();
			
			if (!StringUtils.isEmpty(addressIn.getAddressType())) {
				result.setAddressTypeCode(addressIn.getAddressType());
			}
			if (!StringUtils.isEmpty(addressIn.getAddressTypeDesc())) {
				result.setAddressType(addressIn.getAddressTypeDesc());
			}
			if (!StringUtils.isEmpty(addressIn.getStreetNumber())) {
				result.setStreetNumber(addressIn.getStreetNumber());
			}
			if (!StringUtils.isEmpty(addressIn.getStreetType())
					|| !StringUtils.isEmpty(addressIn.getStreetName())) {
				String[] components = new String[]{addressIn.getStreetType(), addressIn.getStreetName()};
				String streetTypeAndName = StringUtils.join(components, " ");
				streetTypeAndName = streetTypeAndName.trim();
				result.setStreetTypeAndName(streetTypeAndName);
			}
			if (!StringUtils.isEmpty(addressIn.getAddressLine2())) {
				result.setAddressLine2(addressIn.getAddressLine2());
			}
			if (!StringUtils.isEmpty(addressIn.getAddressLine3())) {
				result.setAddressLine3(addressIn.getAddressLine3());
			}
			if (!StringUtils.isEmpty(addressIn.getMailBoxNumber())) {
				result.setMailBoxNumber(addressIn.getMailBoxNumber());
			}
			if (!StringUtils.isEmpty(addressIn.getAddressLine5())) {
				result.setLocality(addressIn.getAddressLine5());
			}
			if (!StringUtils.isEmpty(addressIn.getPostalCd())) {
				result.setPostalCode(addressIn.getPostalCd());
			}
			if (!StringUtils.isEmpty(addressIn.getCityName())) {
				result.setCityName(addressIn.getCityName());
			}
			if (!StringUtils.isEmpty(addressIn.getCountryName())) {
				result.setCountryName(addressIn.getCountryName());
			}
			if (!StringUtils.isEmpty(addressIn.getHexacleVoie())) {
				result.setHexacleVoie(addressIn.getHexacleVoie());
			}
			if (!StringUtils.isEmpty(addressIn.getHexacleLocalite())) {
				result.setHexacleLocalite(addressIn.getHexacleLocalite());
			}
		}
		return result;
	}
	
	/**
	 * Convert a Database PartyRel to a PartyRelBean
	 * @param partyRelIn the database partyRel
	 * @return the corresponding PartRel
	 */
	private static PartyRelBean mdmPartyRelToPartyRelBean(PartyRelResultBean partyRelIn, String mainPartyId) {
		PartyRelBean result = null;
		if (partyRelIn != null) {
			result = new PartyRelBean();
			if (!StringUtils.isEmpty(partyRelIn.getPartyId1())) {
				if (!mainPartyId.equals(partyRelIn.getPartyId1().trim())) {
					result.setPartyId(partyRelIn.getPartyId1());
				}
			}
			if (!StringUtils.isEmpty(partyRelIn.getPartyId2())) {
				if (!mainPartyId.equals(partyRelIn.getPartyId2().trim())) {
					result.setPartyId(partyRelIn.getPartyId2());
				}
			}
			if (!StringUtils.isEmpty(partyRelIn.getRelName())) {
				result.setRelName(partyRelIn.getRelName());
			}
			if (!StringUtils.isEmpty(partyRelIn.getRelDesc())) {
				result.setRelDesc(partyRelIn.getRelDesc());
			}
		}
		return result;
	}

	public static RequestWithParamsBean buildPartyContractRequest(String partyId) {
		Map<String, Object> filterParams = new HashMap<String, Object>();
		
		if (!StringUtils.isEmpty(partyId)) {
			filterParams.put("partyId", partyId);
		}

		// Create the SearchQuery request
		RequestWithParamsBean request = new RequestWithParamsBean();
		request.setSqlQuery(SearchPartyByMdmIdConstants.PARTY_CONTRACT_SEARCH_QUERY);
		request.setParams(filterParams);

		return request;
	}

	public static RequestWithParamsBean buildListAddressRequest(
			List<PartyWithAddressAndContractBean> partyResults) {
		Map<String, Object> filterParams = new HashMap<String, Object>();
		
		if (partyResults != null && !partyResults.isEmpty()){
			List<String> partyIds = new ArrayList<String>();
			for (PartyWithAddressAndContractBean partyResult : partyResults) {
				if(!StringUtils.isEmpty(partyResult.getMdmId())){
					partyIds.add(partyResult.getMdmId());
				}
			}
			filterParams.put("partyIds", partyIds);
		}

		// Create the SearchQuery request
		RequestWithParamsBean request = new RequestWithParamsBean();
		request.setSqlQuery(SearchPartyByMdmIdConstants.PARTY_LIST_ADDRESS_SEARCH_QUERY);
		request.setParams(filterParams);

		return request;
	}

	public static RequestWithParamsBean buildListPartyElectronicAddressRequest(
			List<PartyWithAddressAndContractBean> partyResults) {
		Map<String, Object> filterParams = new HashMap<String, Object>();
		
		if (partyResults != null && !partyResults.isEmpty()){
			List<String> partyIds = new ArrayList<String>();
			for (PartyWithAddressAndContractBean partyResult : partyResults) {
				if(!StringUtils.isEmpty(partyResult.getMdmId())){
					partyIds.add(partyResult.getMdmId());
				}
			}
			filterParams.put("partyIds", partyIds);
		}

		// Create the SearchQuery request
		RequestWithParamsBean request = new RequestWithParamsBean();
		request.setSqlQuery(SearchPartyByMdmIdConstants.PARTY_LIST_ELECTRONIC_ADDRESS_SEARCH_QUERY);
		request.setParams(filterParams);

		return request;
	}

	public static RequestWithParamsBean buildListPartyCrmIdRequest(
			List<PartyWithAddressAndContractBean> partyResults) {
		Map<String, Object> filterParams = new HashMap<String, Object>();
		
		if (partyResults != null && !partyResults.isEmpty()){
			List<String> partyIds = new ArrayList<String>();
			for (PartyWithAddressAndContractBean partyResult : partyResults) {
				if(!StringUtils.isEmpty(partyResult.getMdmId())){
					partyIds.add(partyResult.getMdmId());
				}
			}
			filterParams.put("partyIds", partyIds);
		}

		// Create the SearchQuery request
		RequestWithParamsBean request = new RequestWithParamsBean();
		request.setSqlQuery(SearchPartyByMdmIdConstants.PARTY_LIST_CRM_ID_SEARCH_QUERY);
		request.setParams(filterParams);

		return request;
	}

	public static RequestWithParamsBean buildListPartyLogementIdRequest(
			List<PartyWithAddressAndContractBean> partyResults) {
		Map<String, Object> filterParams = new HashMap<String, Object>();
		
		if (partyResults != null && !partyResults.isEmpty()){
			List<String> partyIds = new ArrayList<String>();
			for (PartyWithAddressAndContractBean partyResult : partyResults) {
				if(!StringUtils.isEmpty(partyResult.getMdmId())){
					partyIds.add(partyResult.getMdmId());
				}
			}
			filterParams.put("partyIds", partyIds);
		}

		// Create the SearchQuery request
		RequestWithParamsBean request = new RequestWithParamsBean();
		request.setSqlQuery(SearchPartyByMdmIdConstants.PARTY_LIST_LOGEMENT_ID_SEARCH_QUERY);
		request.setParams(filterParams);

		return request;
	}

	public static RequestWithParamsBean buildListPartyContractRequest(
			List<PartyWithAddressAndContractBean> partyResults) {
		Map<String, Object> filterParams = new HashMap<String, Object>();
		
		if (partyResults != null && !partyResults.isEmpty()){
			List<String> partyIds = new ArrayList<String>();
			for (PartyWithAddressAndContractBean partyResult : partyResults) {
				if(!StringUtils.isEmpty(partyResult.getMdmId())){
					partyIds.add(partyResult.getMdmId());
				}
			}
			filterParams.put("partyIds", partyIds);
		}

		// Create the SearchQuery request
		RequestWithParamsBean request = new RequestWithParamsBean();
		request.setSqlQuery(SearchPartyByMdmIdConstants.PARTY_LIST_CONTRACT_SEARCH_QUERY);
		request.setParams(filterParams);

		return request;
	}
	
}
